package org.wheel.plugins.toolkit.sql.capability;

import org.wheel.plugins.toolkit.sql.core.AbstractWrapper;
import org.wheel.plugins.toolkit.sql.enums.LogicalOp;
import org.wheel.plugins.toolkit.sql.enums.SqlTimeUnit;
import org.wheel.plugins.toolkit.sql.function.F;
import org.wheel.plugins.toolkit.sql.function.FunctionBuilder;
import org.wheel.plugins.toolkit.sql.helper.SFunction;
import org.wheel.plugins.toolkit.sql.segment.HavingSegment;
import org.wheel.plugins.toolkit.sql.segment.having.HavingGroup;

import java.util.function.Consumer;

/**
 * having 条件
 * @param <W>
 */
public interface LambdaHaving<W extends LambdaHaving<W, T>, T> {
    /** 原子函数 */
    W having(String sql);
    W havingOp(LogicalOp op, Consumer<HavingGroup> consumer);

    default W havingFunction(FunctionBuilder fn){
        return having(fn.getSql());
    }
    /** having 条件,直接写SQL */
    default W having(HavingSegment having){
        return having(having.getSql());
    }

    /** AND 组合 */
    default W havingAnd(Consumer<HavingGroup> consumer){
        return havingOp(LogicalOp.AND, consumer);
    }

    /** OR 组合 */
    default W havingOr(Consumer<HavingGroup> consumer){
        return havingOp(LogicalOp.OR, consumer);
    }

    /* ========== 标量函数快捷方法（可用于 WHERE / HAVING） ========== */
    default W havingDateAdd(SFunction<T,?> col, int amount, SqlTimeUnit unit){
        return havingFunction(F.dateAdd(col, amount, unit, null).bind( (AbstractWrapper<?, ?>) this));   // 直接复用已有方法
    }
    default W havingJsonExtract(SFunction<T,?> col, String path){
        return havingFunction(F.jsonExtract(col, path, null).bind( (AbstractWrapper<?, ?>) this));
    }
}
